<template>
  <div class="file-explorer">
    <div class="page-header">
      <el-button @click="$router.push('/')" type="primary" plain size="small">
        <el-icon><HomeFilled /></el-icon>
        返回首页
      </el-button>
    </div>

    <div class="file-explorer-header">
      <div class="header-top">
        <el-breadcrumb separator="/">
          <el-breadcrumb-item 
            v-for="(item, index) in breadcrumbs" 
            :key="index"
            @click="navigateTo(item.path)"
          >
            {{ item.name }}
          </el-breadcrumb-item>
        </el-breadcrumb>
        
        <el-button-group>
          <el-button 
            type="primary" 
            :icon="Refresh"
            plain
            size="small"
            :loading="refreshing"
            @click="refreshCache"
            title="刷新目录缓存"
          >
            刷新
          </el-button>
        </el-button-group>
      </div>
      
      <div class="toolbar">
        <el-input
          v-model="searchQuery"
          placeholder="搜索文件..."
          prefix-icon="el-icon-search"
          clearable
          @input="handleSearch"
        />
        <el-select v-model="filterType" placeholder="文件类型" clearable>
          <el-option label="所有文件" value="" />
          <el-option label="文件夹" value="directory" />
          <el-option label="文件" value="file" />
        </el-select>
      </div>
    </div>

    <div class="file-explorer-content">
      <el-tree
        ref="fileTree"
        v-loading="loading"
        element-loading-text="加载中..."
        :data="fileTreeData"
        :props="defaultProps"
        node-key="path"
        :load="loadNode"
        lazy
        :filter-node-method="filterNode"
        @node-click="handleNodeClick"
      >
        <template #default="{ node, data }">
          <div class="custom-tree-node">
            <span class="file-icon">
              <el-icon>
                <component :is="getFileIcon(data)" />
              </el-icon>
            </span>
            <span class="file-name">{{ node.label }}</span>
            <span class="file-size" v-if="data.type === 'file'">
              {{ formatFileSize(data.size) }}
            </span>
            <div class="file-actions">
              <el-dropdown 
                trigger="click" 
                @command="handleCommand"
                @click.stop
              >
                <el-button 
                  type="text" 
                  size="small"
                  @click.stop
                >
                  <el-icon><Folder /></el-icon>
                  操作
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item 
                      :command="{ type: 'open', path: data.path }"
                      @click.stop
                    >
                      打开位置
                    </el-dropdown-item>
                    <el-dropdown-item 
                      :command="{ type: 'copy', path: data.path }"
                      @click.stop
                    >
                      复制路径
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </div>
        </template>
      </el-tree>
    </div>

    <el-drawer
      v-model="previewDrawer.visible"
      :title="previewDrawer.title"
      size="50%"
    >
      <div class="preview-content">
        <!-- 根文件类型显示不同的预览内容 -->
        <img 
          v-if="isImage(previewDrawer.file)"
          :src="previewDrawer.file.path"
          alt="预览图片"
        />
        <pre v-else-if="isText(previewDrawer.file)">
          {{ previewDrawer.content }}
        </pre>
        <div v-else class="no-preview">
          该文件类型暂不支持预览
        </div>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'
import { Folder, Document, Picture, HomeFilled, Refresh } from '@element-plus/icons-vue'

export default {
  name: 'FileExplorer',
  components: {
    Folder,
    Document,
    Picture,
    HomeFilled,
    Refresh
  },
  setup() {
    const fileTreeData = ref([])
    const searchQuery = ref('')
    const filterType = ref('')
    const breadcrumbs = ref([{ name: '根目录', path: '' }])
    const previewDrawer = reactive({
      visible: false,
      title: '',
      file: null,
      content: ''
    })
    const fileTree = ref(null)
    const loading = ref(false)
    const openingLocation = ref(false)
    const refreshing = ref(false)

    const defaultProps = {
      children: 'children',
      label: 'name',
      isLeaf: (data) => data.type === 'file'
    }

    const loadNode = async (node, resolve) => {
      if (node.level === 0) {
        loading.value = true
        try {
          const response = await axios.get('/api/file-system/tree')
          resolve(response.data.children)
        } catch (error) {
          ElMessage.error('加载文件系统失败')
          resolve([])
        } finally {
          loading.value = false
        }
      } else {
        loading.value = true
        try {
          const response = await axios.get('/api/file-system/tree', {
            params: {
              path: node.data.path,
              max_depth: 1
            }
          })
          resolve(response.data.children)
        } catch (error) {
          ElMessage.error('加载目录失败')
          resolve([])
        } finally {
          loading.value = false
        }
      }
    }

    const openFileLocation = async (path) => {
      try {
        const response = await axios.post('/api/file-system/open-location', { path })
        if (!response.data.success) {
          throw new Error('打开位置失败')
        }
      } catch (error) {
        console.error('打开文件位置失败:', error)
        ElMessage.error('打开文件位置失败，请尝试使用复制的路径')
        copyPath(path)
      }
    }

    const handleNodeClick = (data) => {
      if (data.type === 'file' && event.detail === 2) {
        previewFile(data)
      }
    }

    const previewFile = async (file) => {
      previewDrawer.file = file
      previewDrawer.title = file.name
      
      if (isText(file)) {
        try {
          const response = await axios.get(`/api/file-system/content?path=${file.path}`)
          previewDrawer.content = response.data
        } catch (error) {
          previewDrawer.content = '无法加载文件内容'
        }
      }
      
      previewDrawer.visible = true
    }

    const formatFileSize = (size) => {
      const units = ['B', 'KB', 'MB', 'GB']
      let index = 0
      while (size >= 1024 && index < units.length - 1) {
        size /= 1024
        index++
      }
      return `${size.toFixed(2)} ${units[index]}`
    }

    const getFileIcon = (data) => {
      if (data.type === 'directory') {
        return 'Folder'
      }
      const extension = data.name.split('.').pop()?.toLowerCase()
      const iconMap = {
        pdf: 'Document',
        txt: 'Document',
        jpg: 'Picture',
        png: 'Picture',
      }
      return iconMap[extension] || 'Document'
    }

    const isImage = (file) => {
      if (!file) return false
      const extension = file.name.split('.').pop()?.toLowerCase()
      return ['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(extension)
    }

    const isText = (file) => {
      if (!file) return false
      const extension = file.name.split('.').pop()?.toLowerCase()
      return ['txt', 'md', 'json', 'js', 'ts', 'html', 'css', 'vue'].includes(extension)
    }

    const filterNode = (value, data) => {
      if (!value) return true
      if (filterType.value && data.type !== filterType.value) return false
      return data.name.toLowerCase().includes(value.toLowerCase())
    }

    const handleSearch = () => {
      fileTree.value?.filter(searchQuery.value)
    }

    const navigateTo = (path) => {
      // 更面包屑导航
      const parts = path.split('/')
      breadcrumbs.value = [
        { name: '根目录', path: '' },
        ...parts.map((part, index) => ({
          name: part,
          path: parts.slice(0, index + 1).join('/')
        }))
      ]
    }

    const handleCommand = async ({ type, path }) => {
      try {
        if (type === 'open') {
          await openFileLocation(path)
        } else if (type === 'copy') {
          await copyPath(path)
        }
      } catch (error) {
        console.error('操作失败:', error)
        ElMessage.error('操作失败')
      }
    }

    const copyPath = async (path) => {
      try {
        await navigator.clipboard.writeText(path)
        ElMessage.success('路径已复制到剪贴板')
      } catch (error) {
        console.error('复制路径失败:', error)
        ElMessage.error('复制路径失败')
      }
    }

    const refreshCache = async () => {
      try {
        refreshing.value = true
        // 清除缓存
        await axios.post('/api/file-system/tree/invalidate-cache')
        // 重新加载当前目录
        if (fileTree.value) {
          fileTree.value.store.root.childNodes.forEach(node => {
            node.expanded = false
          })
          await loadNode({ level: 0 }, (children) => {
            fileTreeData.value = children
          })
        }
        ElMessage.success('刷新成功')
      } catch (error) {
        console.error('刷新失败:', error)
        ElMessage.error('刷新失败')
      } finally {
        refreshing.value = false
      }
    }

    return {
      fileTreeData,
      defaultProps,
      searchQuery,
      filterType,
      breadcrumbs,
      previewDrawer,
      loadNode,
      openFileLocation,
      handleNodeClick,
      formatFileSize,
      getFileIcon,
      isImage,
      isText,
      filterNode,
      handleSearch,
      navigateTo,
      fileTree,
      loading,
      openingLocation,
      handleCommand,
      copyPath,
      refreshing,
      refreshCache,
      Refresh
    }
  }
}
</script>

<style scoped>
.file-explorer {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 20px;
}

.file-explorer-header {
  margin-bottom: 20px;
}

.toolbar {
  display: flex;
  gap: 10px;
  margin-top: 10px;
}

.file-explorer-content {
  flex: 1;
  overflow: auto;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  padding: 8px 0;
  user-select: none;
}

.file-icon {
  margin-right: 8px;
}

.file-name {
  flex: 1;
}

.file-size {
  color: #909399;
  margin: 0 16px;
}

.file-actions {
  opacity: 0;
  transition: opacity 0.2s;
  z-index: 1;
}

.custom-tree-node:hover .file-actions {
  opacity: 1;
}

.preview-content {
  padding: 20px;
  height: 100%;
  overflow: auto;
}

.preview-content img {
  max-width: 100%;
}

.no-preview {
  text-align: center;
  color: #909399;
  padding: 40px;
}

.page-header {
  margin-bottom: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.el-icon {
  margin-right: 4px;
}

.el-dropdown {
  margin-left: 8px;
}

.header-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.el-breadcrumb {
  flex: 1;
  margin-right: 16px;
}

/* 修改工具栏样式 */
.toolbar {
  display: flex;
  gap: 10px;
  margin-top: 10px;
  padding-top: 16px;
  border-top: 1px solid #e4e7ed;
}
</style> 